﻿namespace Extensions.Web.UI
{
    using CachePage;
    using Extensions.Linq;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Threading;
    using System.Web;
    using System.Web.SessionState;
    using System.Web.UI;

    public class UserControl : UserControl
    {
        private TransactionExtensions _transaction = null;
        private Extensions.Linq.ComponentOperator componentOperator = null;
        private InheritStateBag inheritStateBag = null;
        private GuidSession stateGuidSession = null;

        public override void DataBind()
        {
            try
            {
                base.DataBind();
            }
            catch (TargetInvocationException)
            {
            }
            catch (HttpException)
            {
            }
            this.ExtensionsLoad();
        }

        public static Control DataBoundControlHelperFindControl(Control control, string controlID)
        {
            Control namingContainer = control;
            Control control3 = null;
            if (control != control.Page)
            {
                while ((control3 == null) && (namingContainer != control.Page))
                {
                    namingContainer = namingContainer.NamingContainer;
                    if (namingContainer == null)
                    {
                        return null;
                    }
                    control3 = namingContainer.FindControl(controlID);
                }
                return control3;
            }
            return control.FindControl(controlID);
        }

        public static Control DataBoundControlHelperFindControl(Control control, Type containerType)
        {
            for (Control control2 = control.Parent; control2.Parent != null; control2 = control2.Parent)
            {
                if (containerType.IsInstanceOfType(control2))
                {
                    return control2;
                }
            }
            return null;
        }

        protected virtual void ExtensionsDataBind(DataTable table)
        {
        }

        protected virtual void ExtensionsLoad()
        {
            if (this.DataSourceID != "")
            {
                Control control = DataBoundControlHelperFindControl(this, this.DataSourceID);
                if ((control != null) && (control is IDataSource))
                {
                    IDataSource source = (IDataSource) control;
                    source.GetView(this.DataMember).Select(DataSourceSelectArguments.Empty, new DataSourceViewSelectCallback(this.PerformDataBinding));
                }
            }
        }

        protected virtual void ExtensionsTransaction(List<SqlDataSource> SqlDataSourceCollection)
        {
        }

        public void ExtensionsTransactionComplete()
        {
            if (this.IsTransaction)
            {
                this.Transaction.Complete();
            }
        }

        public string GetPageGuidKey()
        {
            if ((this.ViewState["__VIEWSTATEGUID"] != null) && (this.ViewState["__VIEWSTATEGUID"].ToString() != ""))
            {
                return this.ViewState["__VIEWSTATEGUID"].ToString();
            }
            if (!(this.Page.PageAdapter is PageStateAdapter))
            {
                throw new InvalidOperationException("GuidKey/StateSession needed for GuidCachePageStatePersister (ViewState Saved).");
            }
            string pageGuidKey = Guid.NewGuid().ToString();
            ((PageStateAdapter) this.Page.PageAdapter).SetDefaultGuidKey(pageGuidKey);
            return pageGuidKey;
        }

        protected override void OnInit(EventArgs e)
        {
            try
            {
                this.ViewState["__VIEWSTATEGUID"] = this.Page.Request.Form["__VIEWSTATEGUID"];
            }
            catch
            {
            }
            base.OnInit(e);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.ExtensionsLoad();
            this.TransactionLoad();
        }

        public virtual bool OnSuppressExtenderControlScriptDescriptors(ExtenderControl targetControl)
        {
            return false;
        }

        protected override void OnUnload(EventArgs e)
        {
            this.ExtensionsTransactionComplete();
            base.OnUnload(e);
        }

        public void PageMultiThreadStart(PageThread target, string IsAliveStateSessionName)
        {
            PageThreadParameter parameter = new PageThreadParameter(this);
            parameter.IsAliveStateSessionName = IsAliveStateSessionName;
            parameter.Target = target;
            parameter.Thread = new Thread(new ParameterizedThreadStart(this.PageThread_Process));
            parameter.Thread.Start(parameter);
        }

        private void PageThread_Process(object parameter)
        {
            PageThreadParameter parameter2 = (PageThreadParameter) parameter;
            PageThread target = parameter2.Target;
            if (target != null)
            {
                try
                {
                    target();
                }
                catch
                {
                }
            }
            parameter2.Dispose();
        }

        public bool PageThreadIsAlive(string IsAliveStateSessionName)
        {
            return PageThreadParameter.PageThreadIsAlive(this, IsAliveStateSessionName);
        }

        protected virtual void PerformDataBinding(IEnumerable data)
        {
            if ((data != null) && (data is DataView))
            {
                DataTable table = ((DataView) data).Table;
                this.ExtensionsDataBind(table);
            }
        }

        protected void TransactionLoad()
        {
            List<SqlDataSource> sqlDataSourceCollection = new List<SqlDataSource>();
            this.ExtensionsTransaction(sqlDataSourceCollection);
            if (sqlDataSourceCollection.Count > 0)
            {
                for (int i = 0; i < sqlDataSourceCollection.Count; i++)
                {
                    this.Transaction.AddKeep(sqlDataSourceCollection[i]);
                }
                this.IsTransaction = true;
            }
        }

        public virtual void UseModel(object sender)
        {
        }

        public Extensions.Linq.ComponentOperator ComponentOperator
        {
            get
            {
                if (this.componentOperator == null)
                {
                    this.componentOperator = new Extensions.Linq.ComponentOperator();
                }
                return this.componentOperator;
            }
        }

        public string DataMember
        {
            get
            {
                return ((this.ViewState["DataMember"] != null) ? this.ViewState["DataMember"].ToString() : "");
            }
            set
            {
                this.ViewState["DataMember"] = value;
            }
        }

        public string DataSourceID
        {
            get
            {
                return ((this.ViewState["DataSourceID"] != null) ? this.ViewState["DataSourceID"].ToString() : "");
            }
            set
            {
                this.ViewState["DataSourceID"] = value;
            }
        }

        protected virtual InheritStateBag InheritViewState
        {
            get
            {
                if (this.inheritStateBag == null)
                {
                    this.inheritStateBag = new InheritStateBag(this);
                }
                return this.inheritStateBag;
            }
        }

        private bool IsTransaction
        {
            get
            {
                return ((this.ViewState["IsTransaction"] != null) ? ((bool) this.ViewState["IsTransaction"]) : false);
            }
            set
            {
                this.ViewState["IsTransaction"] = value;
            }
        }

        public bool ReadOnly
        {
            get
            {
                return ((this.InheritViewState["ReadOnly"] != null) ? ((bool) this.InheritViewState["ReadOnly"]) : false);
            }
            set
            {
                this.ViewState["ReadOnly"] = value;
            }
        }

        public GuidSession StateSession
        {
            get
            {
                if (this.stateGuidSession == null)
                {
                    this.stateGuidSession = new GuidSession(this);
                }
                return this.stateGuidSession;
            }
        }

        public virtual bool SuppressExtenderControlScript
        {
            get
            {
                return false;
            }
        }

        private TransactionExtensions Transaction
        {
            get
            {
                if (this._transaction == null)
                {
                    this._transaction = new TransactionExtensions();
                }
                return this._transaction;
            }
        }

        public class DescriptorDataItemContainer : Control, IDataItemContainer, INamingContainer, ICustomTypeDescriptor
        {
            public AttributeCollection GetAttributes()
            {
                return TypeDescriptor.GetAttributes(this, true);
            }

            public string GetClassName()
            {
                return TypeDescriptor.GetClassName(this, true);
            }

            public string GetComponentName()
            {
                return TypeDescriptor.GetComponentName(this, true);
            }

            public TypeConverter GetConverter()
            {
                return TypeDescriptor.GetConverter(this, true);
            }

            public EventDescriptor GetDefaultEvent()
            {
                return TypeDescriptor.GetDefaultEvent(this, true);
            }

            public PropertyDescriptor GetDefaultProperty()
            {
                return TypeDescriptor.GetDefaultProperty(this, true);
            }

            public object GetEditor(Type editorBaseType)
            {
                return TypeDescriptor.GetEditor(this, editorBaseType, true);
            }

            public EventDescriptorCollection GetEvents()
            {
                return TypeDescriptor.GetEvents(this, true);
            }

            public EventDescriptorCollection GetEvents(Attribute[] attributes)
            {
                return TypeDescriptor.GetEvents(this, attributes, true);
            }

            public PropertyDescriptorCollection GetProperties()
            {
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this, true);
                return this.ReorderProperties(properties);
            }

            public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
            {
                PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(this, attributes, true);
                return this.ReorderProperties(properties);
            }

            public object GetPropertyOwner(PropertyDescriptor pd)
            {
                return this;
            }

            private PropertyDescriptorCollection ReorderProperties(PropertyDescriptorCollection properties)
            {
                int num;
                string[] strArray = this.DataCustomPropertys.ToArray();
                PropertyDescriptor[] descriptorArray = new PropertyDescriptor[properties.Count + strArray.Length];
                for (num = 0; num < properties.Count; num++)
                {
                    descriptorArray[num] = properties[num];
                }
                for (num = properties.Count; num < descriptorArray.Length; num++)
                {
                    descriptorArray[num] = new CustomPropertyDescriptor(strArray[num - properties.Count]);
                }
                return new PropertyDescriptorCollection(descriptorArray, true);
            }

            protected virtual List<string> DataCustomPropertys
            {
                get
                {
                    return new List<string>();
                }
            }

            public object DataItem
            {
                get
                {
                    return this;
                }
            }

            public virtual int DataItemIndex
            {
                get
                {
                    return -1;
                }
            }

            public virtual int DisplayIndex
            {
                get
                {
                    return -1;
                }
            }

            private class CustomPropertyDescriptor : PropertyDescriptor
            {
                private string _columnName;

                internal CustomPropertyDescriptor(string columnName) : base(columnName, null)
                {
                    this._columnName = columnName;
                }

                public override bool CanResetValue(object component)
                {
                    return false;
                }

                public override object GetValue(object component)
                {
                    return ((UserControl.DescriptorDataItemContainer) component).ViewState[this._columnName];
                }

                public override void ResetValue(object component)
                {
                }

                public override void SetValue(object component, object value)
                {
                    ((UserControl.DescriptorDataItemContainer) component).ViewState[this._columnName] = value;
                }

                public override bool ShouldSerializeValue(object component)
                {
                    return false;
                }

                public override Type ComponentType
                {
                    get
                    {
                        return typeof(UserControl.DescriptorDataItemContainer);
                    }
                }

                public override bool IsReadOnly
                {
                    get
                    {
                        return true;
                    }
                }

                public override Type PropertyType
                {
                    get
                    {
                        return typeof(object);
                    }
                }
            }
        }

        public class GuidSession
        {
            private readonly UserControl UC;

            internal GuidSession(UserControl uc)
            {
                this.UC = uc;
            }

            public object this[string name]
            {
                get
                {
                    return this.Session[this.UC.GetPageGuidKey() + "_ss_" + name];
                }
                set
                {
                    this.Session[this.UC.GetPageGuidKey() + "_ss_" + name] = value;
                }
            }

            private HttpSessionState Session
            {
                get
                {
                    if (this.UC.Session != null)
                    {
                        return this.UC.Session;
                    }
                    return HttpContext.Current.Session;
                }
            }
        }

        public sealed class InheritStateBag
        {
            private readonly UserControl _userControl;

            internal InheritStateBag(UserControl userControl)
            {
                this._userControl = userControl;
            }

            public object this[string key]
            {
                get
                {
                    if (this._userControl.ViewState[key] != null)
                    {
                        return this._userControl.ViewState[key];
                    }
                    object obj2 = null;
                    UserControl control = this._userControl;
                    while (obj2 == null)
                    {
                        control = (UserControl) UserControl.DataBoundControlHelperFindControl(control, typeof(UserControl));
                        if (control != null)
                        {
                            obj2 = control.ViewState[key];
                        }
                        else
                        {
                            return obj2;
                        }
                    }
                    return obj2;
                }
            }
        }

        public delegate void PageThread();

        private class PageThreadParameter
        {
            private readonly HttpApplicationState _Application;
            private readonly string _guidKey;
            public string IsAliveStateSessionName;
            public UserControl.PageThread Target;
            private readonly UserControl UC;

            public PageThreadParameter(UserControl uc)
            {
                this.UC = uc;
                if (this.UC.Application == null)
                {
                    this._Application = HttpContext.Current.Application;
                }
                this._guidKey = this.UC.GetPageGuidKey();
            }

            public void Dispose()
            {
                this.Application.Remove(GetThreadKey(this._guidKey, this.IsAliveStateSessionName));
            }

            private static string GetThreadKey(string GuidKey, string IsAliveStateSessionName)
            {
                return (GuidKey + "_" + IsAliveStateSessionName + "_pageThread");
            }

            public static bool PageThreadIsAlive(UserControl uc, string IsAliveStateSessionName)
            {
                HttpApplicationState application;
                string pageGuidKey = uc.GetPageGuidKey();
                if (uc.Application != null)
                {
                    application = uc.Application;
                }
                else
                {
                    application = HttpContext.Current.Application;
                }
                if (application[GetThreadKey(pageGuidKey, IsAliveStateSessionName)] != null)
                {
                    System.Threading.Thread thread = (System.Threading.Thread) application[GetThreadKey(pageGuidKey, IsAliveStateSessionName)];
                    return thread.IsAlive;
                }
                return false;
            }

            private HttpApplicationState Application
            {
                get
                {
                    if (this.UC.Application != null)
                    {
                        return this.UC.Application;
                    }
                    return this._Application;
                }
            }

            public System.Threading.Thread Thread
            {
                get
                {
                    return (System.Threading.Thread) this.Application[GetThreadKey(this._guidKey, this.IsAliveStateSessionName)];
                }
                set
                {
                    this.Application[GetThreadKey(this._guidKey, this.IsAliveStateSessionName)] = value;
                }
            }
        }
    }
}

